#include "shareManager.h"

#include <QDebug>

TcpClient::TcpClient(QObject *parent):
    QObject(parent)
{
//    qDebug()<<"mianThreadID:"<<QThread::currentThreadId();

}

TcpClient::~TcpClient()
{
    qDebug()<<"TcpClient析构";
}

bool TcpClient::connectServer(QString ipAddr, int port)
{
    socket = new QTcpSocket;

    //关联信号和槽
    connect(socket, SIGNAL(readyRead()), this, SLOT(slot_readTcpData()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(slot_disconnect()));

    //转移到线程并启动
    moveToThread(&workThread);
    workThread.start();

    //连接server
    socket->connectToHost(ipAddr, port);
    if(socket->waitForConnected(1500) == false)
    {
        //释放new的空间
        delete socket;

        return false;
    }

    return true;
}

void TcpClient::slot_readTcpData()
{
    //加入缓冲区
    if(socket->bytesAvailable() > 0)
        sharePointer->rxBuffer.append(socket->readAll());

    //处理缓冲区
    socketBufferHandle(sharePointer->rxBuffer);//改:使用新线程处理
}

void TcpClient::socketBufferHandle(QByteArray &buf)
{
    //防止buffer爆炸，放在前面防止缓冲中冗余数据让下面的 while()做无用功
    if(buf.size() > 768)
    {buf.clear();}

    //没找到帧结束符
    if(!buf.contains('\n'))
    {return;}

    int nFramePos = 0;
    //改：只要含有‘\n’，就解析完，防止漏帧
    while(buf.contains('\n'))
    {
        //将一帧数据取出并从缓冲区移除
        nFramePos = buf.indexOf('\n');
        QByteArray tmpBuf = buf.mid(0, nFramePos + 1);// +1 -> \n
        buf.remove(0, nFramePos + 1);

        //1.判断帧头
        if(tmpBuf[0] != (char)0x55 || tmpBuf[1] != (char)0x55)
        {return;}//错误帧

        //2.校验数据长度
        if((quint8)tmpBuf[3] != (tmpBuf.size()-5))
        {return;}//实际数据长度 != 接收数据长度

        //3.提取功能字
        char funcWord = tmpBuf[2];

        //4.根据功能字解码
        switch(funcWord)
        {
        case (char)0xA2 :
            AHRSHandle(tmpBuf);
            break;

        case (char)0xA3 :
            RCHandle(tmpBuf);
            break;

        case (char)0xA4 :
            GPSHandle(tmpBuf);
            break;

        case (char)0xA5 :
            MOTORHandle(tmpBuf);
            break;

        default : break;
        }
    }
}

void TcpClient::RCHandle(const QByteArray &buf)
{
    sharePointer->lockRC.lock();

    char *p = (char*)(&(sharePointer->RC_Values.CH1));
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockRC.unlock();
}

void TcpClient::AHRSHandle(const QByteArray &buf)
{
    sharePointer->lockAHRS.lock();

    char *p = (char *)&sharePointer->AHRS_values.YAW;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockAHRS.unlock();
}

void TcpClient::GPSHandle(const QByteArray &buf)
{
    sharePointer->lockGPS.lock();

    char *p = (char *)&sharePointer->GPS_values.longtitude;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockGPS.unlock();
}

void TcpClient::MOTORHandle(const QByteArray &buf)
{
    sharePointer->lockMOTOR.lock();

    char *p = (char *)&sharePointer->MOTOR_values.motor1;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockMOTOR.unlock();
}

//断线重连
void TcpClient::slot_disconnect()
{
//    qDebug()<<"Disconnect.";
//    qDebug()<<"slot_disconnect:"<<QThread::currentThreadId();
}

